﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using AhgoraParser.Library.Dtos;

namespace AhgoraParser.Library.Libs
{
    public class DiaController
    {
        public static TimeSpan CargaHoraria { get; set; }
        public static Regex exp;
        static readonly object _locker = new object();
        public string Situacao { get; set; }
        DiaDto diaSelecionado;
        List<TimeSpan> horarios;
        public TimeSpan HorasTrabalhadas { get; set; }
        public bool EmExpediente { get; set; }
        public bool ExcedeuExpediente { get; private set; }
        public bool AntecipouSaida { get; private set; }

        DateTime dataAtual;
        public TimeSpan HoraFinalSugerida { get; set; }
        TimeSpan diferenca;
        public DiaController()
        {
            Situacao = string.Empty;
        }

        private static void InicializarRegex()
        {
            lock(_locker)
            {
                if(exp == null)
                {
                    exp = new Regex( @"^((0?\d|1\d|2[0-3])\:[0-5]\d\s*,?\s*)+$" );
                }
            }
        }

        public void InicializarValores( DiaDto dia )
        {
            InicializarRegex();
            diaSelecionado = dia;
            if(ValidarDados())
            {
                dataAtual = dia.Data;
                horarios = ConverterHorariosToTimeSpan( dia.Horarios );
                AntecipouSaida = false;
                ExcedeuExpediente = false;
                diferenca = TimeSpan.Zero;
                CalcularHorasTrabalhadas();
            }
            else
                throw new Exception( "Não foi possível calcular, existem valores inválidos" );
        }

        public void InicializarValores( DateTime dataSelecionada, string horarios )
        {
            InicializarValores( new DiaDto( dataSelecionada, horarios ) );
        }

        public void CalcularHorasTrabalhadas()
        {
            if(horarios == null)
            {
                HorasTrabalhadas = TimeSpan.Zero;
                return;
            }

            TimeSpan diferenca = TimeSpan.Zero, total = TimeSpan.Zero;
            int indiceMax = 0;
            bool par = horarios.Count % 2 == 0;
            if(par)
                indiceMax = horarios.Count - 1;
            else
                indiceMax = horarios.Count - 2;

            for(int i = 0; i < indiceMax; i += 2)
            {
                diferenca = horarios[( i + 1 )] - horarios[i];
                total += diferenca;
                if(( i + 1 ) == indiceMax)
                    break;
            }
            HorasTrabalhadas = total;
            //TimeSpan agora = DateTime.Now.TimeOfDay;
            //if(EmExpediente && horarios.Last() < agora)
            //{
            //    HorasTrabalhadas += ( agora - horarios.Last() );
            //    horarios.Add( agora );
            //}
            CalcularHoraFinalSugerida();
        }


        public void CalcularHoraFinalSugerida()
        {
            if(HorasTrabalhadas == CargaHoraria)
                return;
            TimeSpan ultimoHorario = horarios.Max( o => o );

            if(HorasTrabalhadas > CargaHoraria)
            {
                ExcedeuExpediente = true;
                diferenca = HorasTrabalhadas - CargaHoraria;
                HoraFinalSugerida = ultimoHorario - diferenca;
                Situacao = string.Format("Regime extraordinário de {0} a partir de {1}", diferenca.ToString(@"hh\:mm"), HoraFinalSugerida.ToString(@"hh\:mm"));
            }
            else
            {
                if(!dataAtual.Date.Equals( DateTime.Now.Date ))
                    AntecipouSaida = true;
                diferenca = CargaHoraria - HorasTrabalhadas;
                HoraFinalSugerida = ultimoHorario + diferenca;
                if(AntecipouSaida)
                    Situacao = string.Format( "Saída antecipada de {0}", diferenca.ToString( @"hh\:mm" ) );
            }
        }

        public static List<TimeSpan> ConverterHorariosToTimeSpan( string horarios )
        {
            List<TimeSpan> horariosTimeSpan;
            if(ValidarStringHorarios( horarios ))
                return horariosTimeSpan = horarios.Split( ',' ).Select( o => ConverterHorarioToTimeSpan( o.Trim() ) ).OrderBy( o => o.Ticks ).ToList();
            else
                return new List<TimeSpan>();
        }

        private static TimeSpan ConverterHorarioToTimeSpan( string valorHoraEmString )
        {
            int horas, minutos;
            string[] valoresSplit = valorHoraEmString.Split( ':' );
            horas = Convert.ToInt32( valoresSplit[0] );
            minutos = Convert.ToInt32( valoresSplit[1] );
            return new TimeSpan( horas, minutos, 0 );
        }

        private bool ValidarDados()
        {
            if(diaSelecionado == null)
                return false;
            return ValidarStringHorarios( diaSelecionado.Horarios );
        }

        public static bool ValidarStringHorarios( string horario )
        {
            InicializarRegex();
            if(string.IsNullOrEmpty( horario ) || !exp.IsMatch( horario ))
                return false;
            else
                return true;
        }
    }
}
